package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.RedisCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author xiongkunYang
 */
@Service
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    private final BaseCategory1Mapper baseCategory1Mapper;

    private final BaseCategory2Mapper baseCategory2Mapper;

    private final BaseCategory3Mapper baseCategory3Mapper;

    private final BaseCategoryViewMapper baseCategoryViewMapper;

    private final BaseAttributeMapper baseAttributeMapper;

    public BaseCategoryServiceImpl(BaseCategory1Mapper baseCategory1Mapper,
                                   BaseCategory2Mapper baseCategory2Mapper,
                                   BaseCategory3Mapper baseCategory3Mapper,
                                   BaseCategoryViewMapper baseCategoryViewMapper,
                                   BaseAttributeMapper baseAttributeMapper) {
        this.baseCategory1Mapper = baseCategory1Mapper;
        this.baseCategory2Mapper = baseCategory2Mapper;
        this.baseCategory3Mapper = baseCategory3Mapper;
        this.baseCategoryViewMapper = baseCategoryViewMapper;
        this.baseAttributeMapper = baseAttributeMapper;
    }


    /**
     * 查询所有分类（1、2、3级分类）
     * 数据从封装分类视图中获取，在业务代码中进行业务处理
     */
    @Override
    @RedisCache(prefix = "baseCategoryList:")
    public List<JSONObject> getBaseCategoryList() {
        // 创建期望返回的数据集合
        List<JSONObject> baseCategoryList = new ArrayList<>();

        // 查询分类视图获取三级分类中所有的分类数据
        List<BaseCategoryView> baseCategoryViews = this.baseCategoryViewMapper.selectList(null);
        if (CollectionUtil.isEmpty(baseCategoryViews)) {
            return baseCategoryList;
        }

        // 对所有分类数据根据一级分类id和二级分类进行多级分组：一级 -> 二级 -> 三级
        Map<Long, Map<Long, List<BaseCategoryView>>> grouped = baseCategoryViews.stream()
                .collect(Collectors.groupingBy(
                        BaseCategoryView::getCategory1Id,
                        Collectors.groupingBy(BaseCategoryView::getCategory2Id)
                ));

        // 遍历最外层的一级分类集合，每遍历一次处理一个一级分类
        for (Map.Entry<Long, Map<Long, List<BaseCategoryView>>> category1Entry : grouped.entrySet()) {
            Long category1Id = category1Entry.getKey();
            Map<Long, List<BaseCategoryView>> category2Map = category1Entry.getValue();

            // 获取一级分类名称
            String category1Name = Optional.ofNullable(CollectionUtil.getFirst(category2Map.values().stream()
                            .flatMap(List::stream).toList()))
                    .map(BaseCategoryView::getCategory1Name).orElse("");
            // 构建一级分类JSON对象
            JSONObject jsonObject1 = createCategoryJson(category1Id, category1Name);

            // 创建二级分类JSON对象集合，后期添加到一级分类JSON对象中
            List<JSONObject> jsonObject2List = buildSecondAndThirdCategories(category2Map);

            // 将构建二级分类集合放入一级分类对象中"categoryChild"属性中
            jsonObject1.put("categoryChild", jsonObject2List);
            baseCategoryList.add(jsonObject1);
        }

        return baseCategoryList;
    }

    // 构建 category JSON 对象
    private JSONObject createCategoryJson(Long id, String name) {
        JSONObject json = new JSONObject();
        json.put("categoryId", id);
        json.put("categoryName", name);
        return json;
    }

    @Override
    @RedisCache(prefix = "attributesByCategory1Id:")
    public List<BaseAttribute> getAttributesByCategory1Id(Long category1Id) {
        return this.baseAttributeMapper.selectListByCategory1Id(category1Id);
    }

    @Override
    @RedisCache(prefix = "category3View:")
    public BaseCategoryView getCategoryViewByCategory3Id(Long category3Id) {
        return this.baseCategoryViewMapper.selectById(category3Id);
    }

    @Override
    @RedisCache(prefix = "topBaseCategory3:")
    public List<BaseCategory3> getTopBaseCategory3(Long category1Id) {
        // 创建期望返回的三级分类集合
        List<BaseCategory3> baseCategory3List = new ArrayList<>();
        // 根据一级分类ID查询二级分类集合，得到二级分类ID集合
        List<BaseCategory2> baseCategory2List = this.baseCategory2Mapper.selectList(new LambdaQueryWrapper<BaseCategory2>()
                .eq(BaseCategory2::getCategory1Id, category1Id));
        List<Long> category2IdList = baseCategory2List.stream().map(BaseCategory2::getId).toList();

        if (CollectionUtil.isNotEmpty(category2IdList)) {
            baseCategory3List = this.baseCategory3Mapper.selectList(new LambdaQueryWrapper<BaseCategory3>()
                    // 筛选出二级分类下的所有三级分类
                    .in(BaseCategory3::getCategory2Id, category2IdList)
                    // 是否需要置顶
                    .eq(BaseCategory3::getIsTop, 1)
                    // 根据序号升序排序
                    .orderByAsc(BaseCategory3::getOrderNum)
                    // 获取前7个三级分类
                    .last(" limit 7 "));
        }
        return baseCategory3List;
    }

    @Override
    @RedisCache(prefix = "baseCategoryListByCategory1Id:")
    public JSONObject getBaseCategoryListByCategory1Id(Long category1Id) {

        // 根据一级分类id查询视图获取分类集合
        List<BaseCategoryView> baseCategoryViews = this.baseCategoryViewMapper.selectList(new LambdaQueryWrapper<BaseCategoryView>()
                .eq(BaseCategoryView::getCategory1Id, category1Id));
        if (CollectionUtil.isNotEmpty(baseCategoryViews)) {
            // 创建期望返回的一级分类对象
            String category1Name = baseCategoryViews.get(0).getCategory1Name();
            JSONObject jsonObject1 = this.createCategoryJson(category1Id, category1Name);

            // 对分类集合根据二级分类id进行分组
            Map<Long, List<BaseCategoryView>> category2Map = baseCategoryViews.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));

            // 创建二级分类JSON对象集合，后期添加到一级分类JSON对象中
            List<JSONObject> jsonObject2List = buildSecondAndThirdCategories(category2Map);

            // 将构建二级分类集合放入一级分类对象中"categoryChild"属性中
            jsonObject1.put("categoryChild", jsonObject2List);
            return jsonObject1;
        }
        return new JSONObject();
    }

    private List<JSONObject> buildSecondAndThirdCategories(Map<Long, List<BaseCategoryView>> category2Map) {
        List<JSONObject> jsonObject2List = new ArrayList<>();

        // 遍历二级分类集合，每遍历一次处理一个二级分类
        for (Map.Entry<Long, List<BaseCategoryView>> category2Entry : category2Map.entrySet()) {
            Long category2Id = category2Entry.getKey();
            List<BaseCategoryView> category2List = category2Entry.getValue();

            // 获取二级分类名称
            String category2Name = Optional.ofNullable(CollectionUtil.getFirst(category2List))
                    .map(BaseCategoryView::getCategory2Name).orElse("");

            // 构建二级分类JSON对象
            JSONObject jsonObject2 = createCategoryJson(category2Id, category2Name);

            // 获取三级分类JSON对象集合
            List<JSONObject> jsonObject3List = category2List.stream()
                    // 构建三级分类JSON对象
                    .map(category3 -> createCategoryJson(
                            category3.getCategory3Id(),
                            category3.getCategory3Name()))
                    .toList();

            // 将构建三级分类集合放入二级分类对象中"categoryChild"属性中
            jsonObject2.put("categoryChild", jsonObject3List);
            jsonObject2List.add(jsonObject2);
        }

        return jsonObject2List;
    }


}
